<?php

function getResourceID($socket) {
	$ResourceString = (string) $socket;
	$reg = "/Resource id #(\d+)/i";
	$rep = "$1";
	return (int) preg_replace($reg, $rep, $ResourceString);
}

// main block;
error_reporting ( 1 );
ini_set ( 'display_errors', '1' );

set_time_limit (0);

define('SOCKET_SERVER_PORT',5222);


/**
 * A maximum of backlog incoming connections will be queued for processing.
 * If a connection request arrives with the queue full the client may receive an error with an indication of
 * ECONNREFUSED, or, if the underlying protocol supports retransmission, the request may be ignored so that
 * retries may succeed.
 *
 * The maximum number passed to the backlog  parameter highly depends on the underlying platform.
 * On Linux, it is silently truncated to SOMAXCONN.
 * On win32, if passed SOMAXCONN, the underlying service provider responsible for the socket will set
 * the backlog to a maximum reasonable value. There is no standard provision to find out the actual
 * backlog value on this platform.
 */
define('SOMAXCONN',10);

$socket = socket_create ( AF_INET, SOCK_STREAM, SOL_TCP );

socket_set_option ( $socket, SOL_SOCKET, SO_REUSEADDR, 1 );
socket_bind ( $socket, 0, SOCKET_SERVER_PORT );
socket_listen ( $socket, SOMAXCONN );
$mainsocketID = getResourceID($socket);
$clients = array ($mainsocketID=> $socket);

while ( TRUE ) {
	$read = $clients; // because socket_select removes all clients that are not sending data from read
	$ready = socket_select ( $read, $write = NULL, $except = NULL, $tv_sec = NULL );
	foreach($read as $read_socket) {
		$accept_id = getResourceID($read_socket);
		socket_getpeername ( $read_socket, $ip );
		if($mainsocketID == $accept_id) { // its a new client
			$accept = socket_accept($read_socket);
			array_push($clients, $accept); // normally resource is allocated in sequential order..
			socket_getpeername ( $accept, $ip );
			echo "New Client Connected $ip".PHP_EOL;
			$data = socket_read ( $read_socket, 1024 );
			//var_dump($data);
			continue;
		}
		$data = socket_read ( $read_socket, 1024 );

		echo("$ip is Sending : $data".PHP_EOL);
		
		if ($data === '</stream:stream>') { // may be other for a protocol
			//socket_write ( $clients [$accept_id], 'Thanks for trying my Custom Socket Server, goodbye.'.PHP_EOL);
			echo 'Client ', $ip, ' is exiting.', PHP_EOL;
			socket_close($clients [$accept_id]);
			unset ( $clients [$accept_id] );
			
		}
		
		if ($data == "") {
			socket_close($clients [$accept_id]);
			unset ( $clients [$accept_id] );
			echo "Client disconnected!\n";
		}
		 //else // business logic goes here
			//echo("$ip is Sending : $data".PHP_EOL);
	}
}